package com.example.base.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.base.excetion.GlobalExcetion;
import com.example.base.system.domain.SysConfig;
import com.example.base.system.domain.vo.SysConfigEnum;
import com.example.base.system.domain.vo.SysConfigVo;
import com.example.base.system.domain.vo.SystemConfigVo;
import com.example.base.system.mapper.SysConfigMapper;
import com.example.base.system.service.SysConfigService;
import com.example.base.utils.EnumToListConverter;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author xiong
 * @since 2024-02-07
 */
@Service
@Transactional
@CacheConfig(cacheNames = "SysConfigServiceImpl")
public class SysConfigServiceImpl extends ServiceImpl<SysConfigMapper, SysConfig> implements SysConfigService {

    @Cacheable(cacheNames = "sysconfig",key = "#id")
    @Override
    public SysConfig getById(Serializable id){
        return super.getById(id);
    }

    @CacheEvict(cacheNames = "sysconfig", key = "#id")
    @Override
    public boolean removeById(Serializable id) {
        return super.removeById(id);
    }

    @CacheEvict(cacheNames = "sysconfig", key = "#sysconfig.id")
    @Override
    public boolean updateById(SysConfig sysconfig) {
        return super.updateById(sysconfig);
    }

    @CachePut(cacheNames = "sysconfig", key = "#sysconfig.id")
    public SysConfig saveSysConfig(SysConfig sysconfig) throws GlobalExcetion {
        super.save(sysconfig);
        return sysconfig;
    }

    @CacheEvict(cacheNames = "sysconfig", key = "#sysconfig.id")
    public SysConfig updateSysConfigById(SysConfig sysconfig) throws GlobalExcetion{
        super.updateById(sysconfig);
        return sysconfig;
    }

    @Override
    public List<Map<String, Object>> getSystemConfigType() {
        SysConfigEnum[] enums=SysConfigEnum.values();
        List<Map<String,Object>> mapList=EnumToListConverter.convert(enums,"type","typeName");
        return mapList;
    }

    @Override
    public List<SysConfig> getSystemSysConfig() {
        LambdaQueryWrapper<SysConfig> lambdaQueryWrapper=new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SysConfig::getConfigPath,SysConfigEnum.SYSTEM.getType());
        return this.baseMapper.selectList(lambdaQueryWrapper);
    }

    @Override
    public List<SysConfig> getMailSysConfig() {
        LambdaQueryWrapper<SysConfig> lambdaQueryWrapper=new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SysConfig::getConfigPath,SysConfigEnum.MAIL.getType());
        return this.baseMapper.selectList(lambdaQueryWrapper);
    }

    @Override
    public List<SysConfig> getExtSysConfig() {
        LambdaQueryWrapper<SysConfig> lambdaQueryWrapper=new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SysConfig::getConfigPath,SysConfigEnum.EXT.getType());
        return this.baseMapper.selectList(lambdaQueryWrapper);
    }

    @Override
    public void updateSysConfig(String configPath, String key, String value) {
        LambdaUpdateWrapper<SysConfig> updateWrapper = new LambdaUpdateWrapper<SysConfig>();
        updateWrapper.set(SysConfig::getConfigValue,value);
        updateWrapper.set(SysConfig::getUpdatedate,new Date());
        updateWrapper.eq(SysConfig::getConfigPath,configPath);
        updateWrapper.eq(SysConfig::getConfigKey,key);
        this.baseMapper.update(null,updateWrapper);
    }

    @Override
    public void saveOrUpdateSysConfig(SysConfigVo vo) throws GlobalExcetion {
        if(vo.getId()!=null){
            SysConfig config=super.getById(vo.getId());
            if(config==null){
                throw new GlobalExcetion(1,"系统错误，请刷新后再试");
            }
            if(!vo.getConfigKey().equals(config.getConfigKey())){
                SysConfig key=getSysConfigByPathAndKey(SysConfigEnum.EXT.getType(),config.getConfigKey());
                if(key!=null){
                    throw new GlobalExcetion(1,"key: "+vo.getConfigKey()+" 数据已存在");
                }
            }
            if(vo.getConfigName()!=null){
                config.setConfigName(vo.getConfigName());
            }
            config.setConfigValue(vo.getConfigValue());
            super.baseMapper.updateById(config);
        }else {
            SysConfig key=getSysConfigByPathAndKey(SysConfigEnum.EXT.getType(),vo.getConfigKey());
            if(key!=null){
                throw new GlobalExcetion(1,"key: "+vo.getConfigKey()+" 数据已存在");
            }
            SysConfig sysConfig=new SysConfig();
            sysConfig.setConfigKey(vo.getConfigKey());
            sysConfig.setConfigValue(vo.getConfigValue());
            sysConfig.setConfigName(vo.getConfigName());
            sysConfig.setDeleted(0);
            sysConfig.setCreatedate(new Date());
            sysConfig.setUpdatedate(new Date());
            sysConfig.setConfigPath(SysConfigEnum.EXT.getType());
            super.baseMapper.insert(sysConfig);
        }
    }

    @Override
    public SysConfig getSysConfig(String configPath, String configKey) {
        LambdaUpdateWrapper<SysConfig> lambdaUpdateWrapper=new LambdaUpdateWrapper<>();
        lambdaUpdateWrapper.eq(SysConfig::getConfigPath,configPath);
        lambdaUpdateWrapper.eq(SysConfig::getConfigKey,configKey);
        return this.baseMapper.selectOne(lambdaUpdateWrapper);
    }

    @Override
    public String getInitPassWord() {
        return getSysConfigByPathAndKey(SysConfigEnum.SYSTEM.getType(),"restartPassword").getConfigValue();
    }

    public SysConfig getSysConfigByPathAndKey(String path,String key){
        LambdaQueryWrapper<SysConfig> lambdaQueryWrapper=new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SysConfig::getConfigPath,path);
        lambdaQueryWrapper.eq(SysConfig::getConfigKey,key);
        SysConfig sysConfig=this.baseMapper.selectOne(lambdaQueryWrapper);
        return sysConfig;
    }


}
